import {
  useIntersectionObserver,
  PdfJs,
  Spinner,
  VisibilityChanged,
} from "../../core";

import ThumbnailItem from "./ThumbnailItem";
import { FC, useLayoutEffect, useRef, useState } from "react";

const THUMBNAIL_WIDTH = 100;

interface ThumbnailContainerProps {
  doc: PdfJs.PdfDocument;
  isActive: boolean;
  pageHeight: number;
  pageIndex: number;
  pageWidth: number;
  rotation: number;
  onActive(target: HTMLElement): void;
}

interface PageState {
  height: number;
  isCalculated: boolean;
  page: PdfJs.Page | null;
  viewportRotation: number;
  width: number;
}

const ThumbnailContainer: FC<ThumbnailContainerProps> = ({
  doc,
  isActive,
  pageHeight,
  pageIndex,
  pageWidth,
  rotation,
  onActive,
}) => {
  const [pageSize, setPageSize] = useState<PageState>({
    height: pageHeight,
    isCalculated: false,
    page: null,
    viewportRotation: 0,
    width: pageWidth,
  });
  const visibilityRef = useRef<VisibilityChanged>({
    isVisible: false,
    ratio: 0,
  });
  const { isCalculated, page, height, width } = pageSize;

  const scale = width / height;
  const isVertical = Math.abs(rotation) % 180 === 0;
  const w = isVertical ? THUMBNAIL_WIDTH : THUMBNAIL_WIDTH / scale;
  const h = isVertical ? THUMBNAIL_WIDTH / scale : THUMBNAIL_WIDTH;

  useLayoutEffect(() => {
    if (!isActive || !containerRef.current) {
      return;
    }
    const ele = containerRef.current;
    const visibility = visibilityRef.current;
    if (!visibility.isVisible || visibility.ratio < 1) {
      onActive(ele);
    }
  }, [isActive]);

  const onVisibilityChanged = (params: VisibilityChanged): void => {
    visibilityRef.current = params;
    if (params.isVisible && !isCalculated) {
      doc.getPage(pageIndex + 1).then((pdfPage) => {
        const viewport = pdfPage.getViewport({ scale: 1 });

        setPageSize({
          height: viewport.height,
          isCalculated: true,
          page: pdfPage,
          viewportRotation: viewport.rotation,
          width: viewport.width,
        });
      });
    }
  };

  // To support the document which is already rotated
  const rotationNumber = (rotation + pageSize.viewportRotation) % 360;

  const containerRef = useIntersectionObserver({
    onVisibilityChanged,
  });

  return (
    <div
      className="rpv-thumbnail__container"
      ref={containerRef}
      style={{
        height: `${h}px`,
        width: `${w}px`,
      }}
    >
      {!page ? (
        <Spinner />
      ) : (
        <ThumbnailItem
          page={page}
          pageHeight={isVertical ? height : width}
          pageWidth={isVertical ? width : height}
          rotation={rotationNumber}
          thumbnailHeight={h}
          thumbnailWidth={w}
        />
      )}
    </div>
  );
};

export default ThumbnailContainer;
